﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using SimpleSocket.Samples.ChatCommon;

namespace SimpleSocket.Samples.ChatServer
{
    public class ChatClient : IDisposable
    {
        public SimpleSocketClient Client { get; set; }
        public string UserName { get; set; }
        private IList<ChatClient> ClientList;

        public ChatClient(SimpleSocketClient client, IList<ChatClient> clientList)
        {
            ClientList = clientList;
            Client = client;
            Client.Disconnected += new ConnectionStateEventHandler(Client_Disconnected);
            Client.MessageReceived += new MessageReceivedEventHandler(Client_MessageReceived);
            UserName = Client.Request<string>(5, (int)MessageType.RequestUserName);

            if (UserName == null)
                client.Disconnect(); // if they did not respond disconnect them.

            foreach (ChatClient c in clientList)
                c.UserJoined(UserName);
        }

        void Client_MessageReceived(object sender, ReceivedMessageEventArgs Args)
        {
            MessageType messageType = (MessageType)Args.Command;

            switch (messageType)
            {
                case MessageType.ChatMessage:
                    ChatMessage msg = Args.DataAs<ChatMessage>();
                    
                    // Make sure the user is not spoofing information.
                    msg.FromUser = UserName;
                    msg.MessageDate = DateTime.Now;

                    foreach (ChatClient c in ClientList)
                        c.SendChatMessage(msg);

                    break;

                case MessageType.ListUsers:
                    Args.SendResponce(ClientList.Select(u => u.UserName).OrderBy(u => u).ToArray());
                    break;
            }
        }

        public void UserLeft(string userName)
        {
            if(Client.IsConnected)
                Client.Send((int)MessageType.UserLeft, userName);
        }

        public void UserJoined(string userName)
        {
            if (Client.IsConnected)
                Client.Send((int)MessageType.UserJoined, userName);
        }

        public void SendChatMessage(ChatMessage msg)
        {
            if (Client.IsConnected)
                Client.Send((int)MessageType.ChatMessage, msg);
        }

        void Client_Disconnected(object sender, EventArgs Args)
        {
            if (UserName == null)
                return; // we disconnected them because they did not give us a username.

            foreach (ChatClient c in ClientList)
                c.UserLeft(UserName);
        }

        public void Dispose()
        {
            Client.Dispose();
            Client.Disconnected -= new ConnectionStateEventHandler(Client_Disconnected);
            Client.MessageReceived -= new MessageReceivedEventHandler(Client_MessageReceived);
        }
    }
}
